package com.jdcjk.util;

import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.model.LatLng;
import com.jdcjk.MainApp;
import com.jdcjk.project.car.model.entity.TerminalPathBean;

import java.util.ArrayList;
import java.util.List;

import static com.jdcjk.util.GaoDeMapUtil.transformLat;
import static com.jdcjk.util.GaoDeMapUtil.transformLon;

/**
 * Created by Administrator on 2017/2/13 0013.
 */

public class BaiDuMapUtil {
    public static LocationClient mLocationClient = null;
    public static double pi = 3.1415926535897932384626;
    public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    public static double a = 6378245.0;
    public static double ee = 0.00669342162296594323;

    /**
     * 获得当前位置
     *
     * @param bdLocationListener 回调接口，可以获得对应的位置信息
     */
    public static void getLocation(BDLocationListener bdLocationListener) {
        mLocationClient = new LocationClient(MainApp.getInstance());
        //声明LocationClient类
        mLocationClient.registerLocationListener(bdLocationListener);
        //注册监听函数
        LocationClientOption option = new LocationClientOption();

        //可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，默认gcj02，设置返回的定位结果坐标系
        option.setCoorType("bd09ll");
        //可选，设置是否需要地址信息，默认不需要
        option.setIsNeedAddress(false);
        //可选，默认false,设置是否使用gps
//        option.setOpenGps(true);
        //可选，默认false，设置是否当GPS有效时按照1S/1次频率输出GPS结果
//        option.setLocationNotify(true);
        //可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationDescribe(false);
        //可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIsNeedLocationPoiList(false);
        //可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
//        option.setIgnoreKillProcess(true);
        //可选，默认false，设置是否收集CRASH信息，默认收集
        option.SetIgnoreCacheException(false);
        //可选，默认false，设置是否需要过滤GPS仿真结果，默认需要
        option.setEnableSimulateGps(false);
        mLocationClient.setLocOption(option);
        mLocationClient.start();
    }


    /**
     * 根据距离返回高德地图缩放登记
     *
     * @param distance 起点与终点之间的距离
     * @return 缩放等级
     */
    public static float getZoomLevelByDistance(double distance) {
        float zoomLevel;
        distance = Math.abs(distance);
        if (distance >= 0 && distance <= 20) {
            zoomLevel = 21.0f;
        } else if (distance > 20 && distance <= 50) {
            zoomLevel = 20.0f;
        } else if (distance > 50 && distance <= 100) {
            zoomLevel = 19.0f;
        } else if (distance > 100 && distance <= 250) {
            zoomLevel = 18.0f;
        } else if (distance > 250 && distance <= 500) {
            zoomLevel = 17.0f;
        } else if (distance > 500 && distance <= 1000) {
            zoomLevel = 16.0f;
        } else if (distance > 1000 && distance <= 2500) {
            zoomLevel = 15.0f;
        } else if (distance > 2500 && distance <= 5000) {
            zoomLevel = 14.0f;
        } else if (distance > 5000 && distance <= 10000) {
            zoomLevel = 13.0f;
        } else if (distance > 10000 && distance < 25000) {
            zoomLevel = 12.0f;
        } else if (distance > 25000 && distance <= 50000) {
            zoomLevel = 11.0f;
        } else if (distance > 50000 && distance <= 100000) {
            zoomLevel = 10.0f;
        } else if (distance > 100000 && distance <= 125000) {
            zoomLevel = 9.0f;
        } else if (distance > 125000 && distance <= 250000) {
            zoomLevel = 8.0f;
        } else if (distance > 250000 && distance <= 500000) {
            zoomLevel = 7.0f;
        } else if (distance > 5000000 && distance <= 10000000) {
            zoomLevel = 6.0f;
        } else if (distance > 10000000 && distance <= 25000000) {
            zoomLevel = 5.0f;
        } else if (distance > 25000000 && distance <= 50000000) {
            zoomLevel = 4.0f;
        } else {
            zoomLevel = 3.0f;
        }
        return zoomLevel;
    }

    /**
     * 在两个坐标间插入八条数据，可用于标志物在百度地图的平滑移动
     *
     * @param lastLatLng
     * @param nowLatLng
     * @return
     */
    public static List<LatLng> coordinatesInterpolation(LatLng lastLatLng, LatLng nowLatLng) {
        List<LatLng> latLngList = new ArrayList<>();
        double latGap = nowLatLng.latitude - lastLatLng.latitude;
        double lonGap = nowLatLng.longitude - lastLatLng.longitude;
        double gaoLat = latGap / 10;
        double gaoLon = lonGap / 10;
        for (int i = 0; i < 10; i++) {
            LatLng latLng = new LatLng(lastLatLng.latitude + i * gaoLat, lastLatLng.longitude + gaoLon * i);
            latLngList.add(latLng);
        }
        return latLngList;
    }

    /**
     * 将地球坐标系（WGS84）集合 转换成高德坐标系(GCJ-02)集合
     *
     * @param latLngList
     * @return
     */
    public static List<LatLng> baiduLatLngListEncrypt(List<LatLng> latLngList) {
        for (int i = 0; i < latLngList.size(); i++) {
            latLngList.set(i, baiduLatLngEncrypt(latLngList.get(i)));
        }
        return latLngList;
    }

    /**
     * 将轨迹回放中的坐标系集合 (WGS84) 转换成百度坐标系 (BD-09)集合
     *
     * @param terminalPathBeanList 轨迹点list
     * @return
     */
    public static List<TerminalPathBean> baiduTerminalPathListEncrypt(List<TerminalPathBean> terminalPathBeanList) {
        for (int i = 0; i < terminalPathBeanList.size(); i++) {
            LatLng baiduLatLng = new LatLng(terminalPathBeanList.get(i).getLatitude(), terminalPathBeanList.get(i).getLongitude());
            baiduLatLng = baiduLatLngEncrypt(baiduLatLng);
            terminalPathBeanList.get(i).setLatLng(baiduLatLng.latitude, baiduLatLng.longitude);
        }
        return terminalPathBeanList;
    }

    /**
     * 将地球坐标系（WGS84） 转换成百度坐标系 (BD-09)
     *
     * @param latLng
     * @return
     */
    public static LatLng baiduLatLngEncrypt(LatLng latLng) {
        LatLng newLatlng;
        newLatlng = wgs84_To_Gcj02(latLng.latitude, latLng.longitude);
        newLatlng = gcj02_To_Bd09(newLatlng.latitude, newLatlng.longitude);
        return newLatlng;
    }

    public static List<LatLng> gaodeListToBaiduList(List<com.amap.api.maps.model.LatLng> latLngList) {
        List<LatLng> encrypyList = new ArrayList<>();
        LatLng newLatLng;
        for (int i = 0; i < latLngList.size(); i++) {
            newLatLng = gcj02_To_Bd09(latLngList.get(i).latitude, latLngList.get(i).longitude);
            encrypyList.add(newLatLng);
        }
        return encrypyList;
    }

    /**
     * 将地球坐标系（WGS84） 转换成火星坐标系 (GCJ-02)
     *
     * @param lat
     * @param lon
     * @return
     */
    public static LatLng wgs84_To_Gcj02(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return null;
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new LatLng(mgLat, mgLon);
    }

    /**
     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
     *
     * @param gg_lat
     * @param gg_lon
     */
    public static LatLng gcj02_To_Bd09(double gg_lat, double gg_lon) {
        double x = gg_lon, y = gg_lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new LatLng(bd_lat, bd_lon);
    }

    /**
     * * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
     * bd_lat * @param bd_lon * @return
     */
    public static LatLng bd09_To_Gcj02(double bd_lat, double bd_lon) {
        double x = bd_lon - 0.0065, y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new LatLng(gg_lat, gg_lon);
    }

    /**
     * 百度坐标系 (BD-09-ll) to GPS坐标系 (WGS-84)
     *
     * @param bd_lat 百度坐标纬度
     * @param bd_lon 百度坐标经度
     * @return Gps
     */
    public static LatLng bd09ll_To_Wgs84(double bd_lat, double bd_lon) {
        LatLng latLng = bd09ll_To_Gcj02(bd_lat, bd_lon);
        return gcj02_To_Wgs84(latLng.latitude, latLng.longitude);
    }

    /**
     * 百度坐标系 (BD-09-ll) to 火星坐标系 (GCJ-02)
     *
     * @param bd_lat 百度坐标纬度
     * @param bd_lon 百度坐标经度
     * @return Gps
     */
    public static LatLng bd09ll_To_Gcj02(double bd_lat, double bd_lon) {
        double x = bd_lon - 0.0065, y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new LatLng(gg_lat, gg_lon);
    }

    /**
     * 火星坐标系 (GCJ-02) to GPS坐标系 (WGS-84)
     *
     * @param lat 火星坐标纬度
     * @param lon 火星坐标经度
     * @return Gps
     */
    public static LatLng gcj02_To_Wgs84(double lat, double lon) {
        LatLng latLng = wgs84_To_Gcj02(lat, lon);
        double longitude = lon * 2 - latLng.longitude;
        double latitude = lat * 2 - latLng.latitude;
        return new LatLng(latitude, longitude);
    }

    /**
     * 判断坐标是否在中国
     *
     * @param lat
     * @param lon
     * @return
     */
    public static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }

}
